﻿//#define _CRT_SECURE_NO_WARNINGS 1
//#include<iostream>
//using namespace std;
//class Date
//{
//public:
	//// 1.⽆参构造函数
	//Date()
	//{
	//	_year = 1;
	//	_month = 1;
	//	_day = 1;
	//}
	//// 2.带参构造函数
	//Date(int year, int month, int day)
	//{
	//	_year = year;
	//	_month = month;
	//	_day = day;
	//}
	//// 3.全缺省构造函数
	//Date(int year = 1, int month = 1, int day = 1)
	//{
	//_year = year;
	//_month = month;
	//_day = day;
	//}
//	void Print()
//	{
//		cout << _year << "/" << _month << "/" << _day << endl;
//	}
//	
//	void Init(int year, int month, int day)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	// 如果留下三个构造中的第⼆个带参构造，第⼀个和第三个注释掉
//	// 编译报错：error C2512: “Date”: 没有合适的默认构造函数可⽤
//	Date d1; // 调⽤默认构造函数
//	d1.Print();
//	//Date d2(2025, 1, 1); // 调⽤带参的构造函数
//
//	// 注意：如果通过⽆参构造函数创建对象时，对象后⾯不⽤跟括号，否则编译器⽆法区分这⾥是函数声明还是实例化对象
//	// warning C4930: “Date d3(void)”: 未调⽤原型函数(是否是有意⽤变量定义的?)
//	//Date d3();
//	//d1.Print();
//	//d2.Print();
//	return 0;
//}

//#include<iostream>
//using namespace std;
//typedef int STDataType;
//class Stack
//{
//public:
//	Stack(int n = 4)
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	// ...
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//// 两个Stack实现队列
//class MyQueue
//{
//public:
//	//编译器默认⽣成MyQueue的构造函数调⽤了Stack的构造，完成了两个成员的初始化
//private:
//	Stack pushst;
//	Stack popst;
//};
//int main()
//{
//	MyQueue mq;
//	return 0;
//}


//#include<iostream>
//using namespace std;
//typedef int STDataType;
//class Stack
//{
//public:
//	Stack(int n = 4)
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	~Stack()
//	{
//		cout << "~Stack()" << endl;
//		free(_a);
//		_a = nullptr;
//		_top = _capacity = 0;
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//// 两个Stack实现队列
//class MyQueue
//{
//public:
//	//编译器默认⽣成MyQueue的析构函数调⽤了Stack的析构，释放的Stack内部的资源
//	// 显⽰写析构，也会⾃动调⽤Stack的析构
//		//~MyQueue()
//		//{
//
//		//}
//private:
//
//	//MyQueue 类本身并没有直接开辟内存空间，它只是包含了两个 Stack 类的实例作为成员变量。
//	// 这两个实例的内存管理和资源释放是由 Stack 类来负责的。
//	// 这是 C++ 类和对象机制的一部分，确保了对象的资源在其生命周期结束时得到妥善管理。
//	Stack pushst; //Myqueue类包含两个Stack类的成员对象
//	Stack popst;
//};
//int main()
//{
//	Stack st;
//	MyQueue mq;
//	return 0;
//}


//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//
//	//  error C2652: “Date”: 非法的复制构造函数: 第一个参数不应是“Date”
//
//	Date(const Date& d)
//	{
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
////void Func1(const Date& d)
//void Func1(Date d)
//{
//	cout << &d << endl;
//	d.Print();
//}
//
//int main()
//{
//	Date d1(2024, 7, 12);
//	d1.Print();
//
//	// C++的规定，传值传参要调用拷贝构造
//	Func1(d1);
//
//	Date d2(d1);
//	d2.Print();
//
//	return 0;
//}





#include <iostream>
using namespace std;
typedef int STDataType;
class Stack
{
public:
	Stack(int n = 4)
	{
		_a = (STDataType*)malloc(sizeof(STDataType) * n);
		if (nullptr == _a)
		{
			perror("malloc申请空间失败");
			return;
		}
		_capacity = n;
		_top = 0;
	}

	//拷贝构造
	// st2(st1)
	Stack(const Stack& st)
	{
		cout << "Stack(const Stack& st)" << endl;

		// 需要对_a指向资源创建同样大的资源再拷贝值
		_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
		if (nullptr == _a)
		{
			perror("malloc申请空间失败!!!");
			return;
		}
		memcpy(_a, st._a, sizeof(STDataType) * st._top);
		_top = st._top;
		_capacity = st._capacity;
	}

	void Push(STDataType x)
	{
		if (_top == _capacity)
		{
			int newcapacity = _capacity * 2;
			STDataType* tmp = (STDataType*)realloc(_a, newcapacity *
				sizeof(STDataType));
			if (tmp == NULL)
			{
				perror("realloc fail");
				return;
			}
			_a = tmp;
			_capacity = newcapacity;
		}
		_a[_top++] = x;

	}
	//析构
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	STDataType* _a;
	size_t _capacity;
	size_t _top;
};
//
//int main()
//{
//	Stack st1;
//	st1.Push(1);
//	st1.Push(2);
//
//	// Stack不显示实现拷贝构造，用自动生成的拷贝构造完成浅拷贝
//	// 会导致st1和st2里面的_a指针指向同一块资源，析构时会析构两次，程序崩溃
//	Stack st2(st1);
//
//return 0;
//}




//// 两个Stack实现队列
//class MyQueue
//{
//public:
//private:
//	Stack pushst;
//	Stack popst;
//};
//
//int main()
//{
//	Stack st1;
//	st1.Push(1);
//	st1.Push(2);
//
//	func1(st1);
//
//	// Stack不显示实现拷贝构造，用自动生成的拷贝构造完成浅拷贝
//	// 会导致st1和st2里面的_a指针指向同一块资源，析构时会析构两次，程序崩溃
//	Stack st2(st1);
//	Stack st3 = st1;
//
//	MyQueue mq1;
//	// MyQueue自动生成的拷贝构造，会自动调用Stack拷贝构造完成pushst/popst
//	// 的拷贝，只要Stack拷贝构造自己实现了深拷贝，他就没问题
//	MyQueue mq2(mq1);
//
//	return 0;
//}



//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	// 编译报错：error C2652: “Date”: ⾮法的复制构造函数: 第⼀个参数不应是“Date”
//	//Date(Date d)
//	Date(const Date& d)
//	{
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//	Date(Date * d)
//	{
//		_year = d->_year;
//		_month = d->_month;
//		_day = d->_day;
//	}
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//void Func1(Date d)
//{
//	cout << &d << endl;
//	d.Print();
//}
//// Date Func2()
//Date& Func2()
//{
//	Date tmp(2024, 7, 5);
//	tmp.Print();
//	return tmp;
//}
//int main()
//{
//	Date d1(2024, 7, 5);
//	// C++规定⾃定义类型对象进⾏拷⻉⾏为必须调⽤拷⻉构造，所以这⾥传值传参要调⽤拷⻉构造
//	// 所以这⾥的d1传值传参给d要调⽤拷⻉构造完成拷⻉，传引⽤传参可以较少这⾥的拷⻉
//	Func1(d1);
//	cout << &d1 << endl;
//
//
//	// 这⾥可以完成拷⻉，但是不是拷⻉构造，只是⼀个普通的构造
//	Date d2(&d1);
//	d1.Print();
//	d2.Print();
//
//
//	//这样写才是拷⻉构造，通过同类型的对象初始化构造，⽽不是指针
//	Date d3(d1);
//	d2.Print();
//
//
//	// 也可以这样写，这⾥也是拷⻉构造
//	Date d4 = d1;
//	d2.Print();
//
//
//	// Func2返回了⼀个局部对象tmp的引⽤作为返回值
//	// Func2函数结束，tmp对象就销毁了，相当于了⼀个野引⽤
//	Date ret = Func2();
//	ret.Print();
//	return 0;
//}


//#include<iostream>
//using namespace std;
//// 编译报错：“operator +”必须⾄少有⼀个类类型的形参
////int operator+(int x, int y)
////{
////	return x - y;
////}
//class A
//{
//public:
//	void func()
//	{
//		cout << "A::func()" << endl;
//	}
//};
//typedef void(A::* PF)(); //成员函数指针类型
//int main()
//{
//	// C++规定成员函数要加&才能取到函数指针
//	PF pf = &A::func;
//	A obj;//定义A类对象obj
//	// 对象调⽤成员函数指针时，使⽤.*运算符
//	(obj.*pf)();
//}


//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//	bool operator==(const Date& d)
//	{
//		return _year == d._year
//			&& _month == d._month
//			&& _day == d._day;
//	}
//	Date& operator++()
//	{
//		cout << "前置++" << endl;
//		//...
//		return *this;
//	}
//	Date operator++(int)
//	{
//		Date tmp;
//		cout << "后置++" << endl;
//		//...
//		return tmp;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d1(2024, 7, 5);
//	Date d2(2024, 7, 5);
//	// 运算符重载函数可以显⽰调⽤
//	d1.operator==(d2);
//
//	// 编译器会转换成 d1.operator==(d2);
//	bool ret = d1 == d2;
//	cout << ret << endl;
//
//	// 编译器会转换成 d1.operator++();
//	++d1;
//
//	// 编译器会转换成 d1.operator++(0);
//	d1++;
//	return 0;
//}






//#include<iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//	
//	Date& operator++()
//	{
//		cout << "前置++" << endl;
//		//...
//		return *this;
//	}
//	Date operator++(int)
//	{
//		Date tmp;
//		cout << "后置++" << endl;
//		//...
//		return tmp;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d1(2024, 9, 2);
//	Date d2(2024, 9, 2);
//
//
//	// 编译器会转换成 d1.operator++();
//	++d1;
//
//	// 编译器会转换成 d1.operator++(0);
//	d1++;
//	return 0;
//}




#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	//private:
	int _year;
	int _month;
	int _day;
};
// 重载为全局的⾯临对象访问私有成员变量的问题
// 有⼏种⽅法可以解决：
// 1、成员放公有
// 2、Date提供getxxx函数
// 3、友元函数
// 4、重载为成员函数
bool operator==(const Date& d1, const Date& d2)
{
	return d1._year == d2._year
		&& d1._month == d2._month
		&& d1._day == d2._day;
}
int main()
{
	Date d1(2024, 9, 2);
	Date d2(2024, 9, 2);
	// 运算符重载函数可以显⽰调⽤
	operator==(d1, d2);
	// 编译器会转换成 operator==(d1, d2);
	d1 == d2;
	return 0;
}
